home *** CD-ROM | disk | FTP | other *** search
/ Disc to the Future 2 / Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin / MAC / THINKC / 3_0 / PICTXCMD / PICT.C next >
C/C++ Source or Header  |  1989-04-15  |  7KB  |  330 lines

  1. /******************************************************************
  2.  
  3.          PICT XCMD  -  by Galen Babcock
  4.  
  5.          April 15, 1989
  6.  
  7.          THINK's LightspeedC 3.0 version
  8.  
  9.          Places a QuickDraw generated picture into
  10.          the clipboard for pasting from withing
  11.          HyperCard.  This particular example draws
  12.          a plot of y = sin(x)/x into the rectangle.
  13.  
  14.          XCMD NAME:        PICT
  15.          RESOURCE ID:    403
  16.          
  17.          PICT left,top,right,bottom [,mode[,cycles[,step]]]
  18.  
  19.          INPUT PARAMETERS:
  20.                  1:    left of destination rectangle         (required)
  21.                  2:    top of destination rectangle         (required)
  22.                  3:    right of destination rectangle         (required)
  23.                  4:    bottom of destination rectangle     (required)
  24.                  5:    result mode                         (optional)
  25.                                                          default = 1
  26.                  6:    number of cycles to plot            (optional)
  27.                                                          default = 4
  28.                  7:    pixels per step                        (optional)
  29.                                                          default = 2;
  30.          
  31.          The first four parameters describe the destination rectangle
  32.          for the graphic image, and are required.  The result mode
  33.          parameter can contain one of three legal values...
  34.          
  35.                  1    copy picture into scrap and return
  36.                  2    copy picture into scrap, paste, and return
  37.                  3    copy picture into scrap, paste, choose browse tool,
  38.                      and return
  39.          
  40.          Passing "1" for the result mode parameter causes the graphic to
  41.          be placed in the scrap.  No changes are made to the current
  42.          HyperCard card.  Passing "2" additionally pastes the image onto
  43.          the card, leaving it selected for the user to manipulate with
  44.          HyperCard drawing tools (invert, transparent, rotate, etc.).
  45.          Passing "3" pastes the image onto the card, and then tells HyperCard
  46.          to "Choose browse tool", leaving the image as an integral part
  47.          of the card picture.
  48.   
  49.          EXAMPLE USAGE: 
  50.  
  51.                  PICT 10,10,300,120
  52.                  PICT 10,10,300,120,3
  53.                  PICT 10,10,300,120,3,18.2
  54.                  PICT 10,10,300,120,3,18.2,4
  55.  
  56. ******************************************************************/
  57.  
  58. #include <math.h>
  59. #include <strings.h>
  60. #include <MacTypes.h>
  61. #include <QuickDraw.h>
  62. #include <ScrapMgr.h>
  63. #include <HyperXCMD.h>
  64. #include <SetUpA4.h>
  65.  
  66. int errno;            /* for math library */
  67.  
  68. pascal
  69. void main(paramPtr)
  70. XCmdBlockPtr    paramPtr;
  71. {
  72.     /************************
  73.      *
  74.      *    XCMD variables
  75.      *
  76.      ************************/
  77.     GrafPtr currentPort;
  78.     Rect dstrect;
  79.     PicHandle picH;
  80.     char paramvalue[32];
  81.     long longvalue;
  82.     Boolean showthepen;
  83.     int paramindex;
  84.     int resmode;
  85.     
  86.     /************************
  87.      *
  88.      *    sin(x)/x plotting variables
  89.      *
  90.      ************************/
  91.     double xvalue;
  92.     double xstep;
  93.     double yscale;
  94.     double numcycles;
  95.     int ycenter;
  96.     int xpos,ypos;
  97.     int lastx,lasty;
  98.     int numsteps;
  99.     
  100.     /*
  101.      *
  102.      *    A0 points to our code resource, A4 needs to have this
  103.      *    value to access our global(s).
  104.      *
  105.      *    See pages 84-85 of the THINK C User Manual
  106.      *
  107.      */
  108.     RememberA0();
  109.     SetUpA4();
  110.     
  111.     /*
  112.      *
  113.      *    we need minimally 4 passed parameters
  114.      *    for the destination rect.  Post error
  115.      *    message and return if not.
  116.      *
  117.      */
  118.      
  119.     if ( paramPtr->paramCount < 4 )
  120.         {
  121.             SendCardMessage(paramPtr,(StringPtr)"\pput \"-- ERROR, Sample Usage: PICT left,top,right,bottom\"");
  122.             return;
  123.         }
  124.     
  125.     /*
  126.      *
  127.      *    we have at least 4 parameters, put them into the
  128.      *    left, top, right, bottom coordinates of the
  129.      *    destination rectangle
  130.      *
  131.      */
  132.  
  133.     for (paramindex = 0; paramindex < 4; paramindex++)
  134.         {
  135.             ZeroToPas(paramPtr,(unsigned char *)*(paramPtr->params[paramindex]),(StringPtr)¶mvalue);
  136.             StringToNum(paramvalue,&longvalue);
  137.             switch(paramindex)
  138.                 {
  139.                     case 0:        dstrect.left = (int)longvalue;
  140.                                 break;
  141.                     case 1:        dstrect.top = (int)longvalue;
  142.                                 break;
  143.                     case 2:        dstrect.right = (int)longvalue;
  144.                                 break;
  145.                     case 3:        dstrect.bottom = (int)longvalue;
  146.                                 break;
  147.                 }
  148.         }
  149.  
  150.     /*
  151.      *
  152.      *    test to see if the destination rect is valid,
  153.      *    post error message and return if not
  154.      *
  155.      */
  156.     if ( EmptyRect(&dstrect) )
  157.         {
  158.             SendCardMessage(paramPtr,(StringPtr)"\pput \"-- ERROR, not a valid rectangle\"");
  159.             return;
  160.         }
  161.     
  162.     /*
  163.      *
  164.      *    first optional parameter is the result mode, if it is passed,
  165.      *    store it in local variable "resmode".  If not passed or invalid,
  166.      *    make the default value 1
  167.      *
  168.      */
  169.     if (paramPtr->paramCount > 4)
  170.         {
  171.             ZeroToPas(paramPtr,(unsigned char *)*(paramPtr->params[4]),(StringPtr)¶mvalue);
  172.             StringToNum(paramvalue,&longvalue);
  173.             resmode = (int)longvalue;
  174.             if ( (resmode < 1) || (resmode > 3) )
  175.                 resmode = 1;
  176.         }
  177.     else
  178.         resmode = 1;
  179.  
  180.     /*
  181.      *
  182.      *    if we have 5 parameters, the optional 5th param is the number
  183.      *    of sin(x)/x cycles to plot.  The parameter must be a
  184.      *    legal double value.  If absent or illegal, default
  185.      *    to 4.0 cycles
  186.      *
  187.      */
  188.     if (paramPtr->paramCount > 5)
  189.         {
  190.             ZeroToPas(paramPtr,(unsigned char *)*(paramPtr->params[5]),(StringPtr)¶mvalue);
  191.             StrToExt(paramPtr,(unsigned char *)paramvalue,&numcycles);
  192.             if (numcycles <= 0.0)
  193.                 numcycles = 4.0;
  194.         }
  195.     else
  196.         numcycles = 4.0;
  197.     
  198.     /*
  199.      *
  200.      *    if we have 7 parameters, the 7th parameter is the number of
  201.      *    pixel steps to make for each plot point.  Smaller values result
  202.      *    in higher resolution, larger values result in a "jagged" plot
  203.      *
  204.      */
  205.     if (paramPtr->paramCount > 6)
  206.         {
  207.             ZeroToPas(paramPtr,(unsigned char *)*(paramPtr->params[6]),(StringPtr)¶mvalue);
  208.             StringToNum(paramvalue,&longvalue);
  209.             numsteps = (int)longvalue;
  210.             if ( (numsteps < 1) || (numsteps > 32) )
  211.                 numsteps = 2;
  212.         }
  213.     else
  214.         numsteps = 2;
  215.  
  216.     /*
  217.      *
  218.      *    create a QuickDraw PicHandle to do our
  219.      *    drawing into
  220.      *
  221.      */
  222.     picH = OpenPicture(&dstrect);
  223.     
  224.     /*
  225.      *
  226.      *    uncomment the next line to allow the HyperCard user
  227.      *    to see the drawing taking place.
  228.      *
  229.      */
  230.     
  231.     /*    ShowPen();    */
  232.     
  233.     PenNormal();
  234.     
  235.     /*
  236.      *
  237.      *    begin drawing our image...
  238.      *
  239.      */
  240.     EraseRect(&dstrect);
  241.     FrameRect(&dstrect);
  242.  
  243.     dstrect.bottom -= 1;
  244.     dstrect.right -= 1;
  245.     
  246.     /*
  247.      *
  248.      *    how much does "x" change for each step?
  249.      *
  250.      */
  251.     xstep =  numsteps * ( 2.0 * numcycles * PI ) / (dstrect.right - dstrect.left) ;
  252.     
  253.     /*
  254.      *
  255.      *    set up coordinate system relative to our
  256.      *    destination rectangle
  257.      *
  258.      */
  259.     ycenter = dstrect.top + (dstrect.bottom - dstrect.top) / 2;
  260.     yscale = (dstrect.bottom - dstrect.top) / 2;
  261.     xpos = dstrect.left;
  262.  
  263.     lastx = xpos;
  264.     lasty = ycenter;
  265.     MoveTo(lastx,lasty);
  266.     
  267.     /*
  268.      *
  269.      *    for each iteration, calculate the pixel value of "y",
  270.      *    and draw a line from the last x,y pair to the new
  271.      *    x,y pair
  272.      *
  273.      */
  274.     for ( xvalue = -numcycles * PI; xvalue < ( numcycles * PI); xvalue += xstep )
  275.         {
  276.             ypos = ycenter + (int)(yscale * sin(xvalue)/xvalue);
  277.     
  278.             MoveTo(lastx,lasty);
  279.             LineTo(xpos,ypos);
  280.  
  281.             lastx = xpos;
  282.             lasty = ypos;
  283.             
  284.             xpos += numsteps;
  285.             
  286.             SendCardMessage(paramPtr,(StringPtr)"\pset cursor to busy");
  287.         }
  288.     
  289.     /*
  290.      *
  291.      *    our drawing is complete, so...
  292.      *
  293.      */
  294.     ClosePicture();
  295.     
  296.     /*
  297.      *
  298.      *    place our QuickDraw PICT into the scrap (clipboard) and
  299.      *    if all is successful, tell HyperCard to paste the
  300.      *    the picture.
  301.      *
  302.      */
  303.     if ( (longvalue = LoadScrap()) == noErr )
  304.         {
  305.             if ( (longvalue = ZeroScrap()) == noErr )
  306.                 {
  307.                     HLock((Handle)picH);
  308.                     longvalue = PutScrap(GetHandleSize(picH),'PICT',*picH);
  309.                     HUnlock((Handle)picH);
  310.                     if (resmode > 1)
  311.                         {
  312.                             SendCardMessage(paramPtr,(StringPtr)"\pdomenu Paste Picture");
  313.                             if (resmode > 2)
  314.                                 SendCardMessage(paramPtr,(StringPtr)"\pchoose browse tool");
  315.                         }
  316.                 }
  317.         }
  318.     
  319.     /*
  320.      *
  321.      *    release the memory occupied by our
  322.      *    QuickDraw PicHandle, and restore
  323.      *    registers
  324.      *
  325.      */
  326.     KillPicture(picH);
  327.  
  328.     RestoreA4();
  329. }
  330.